package com.ruoyi.controller;

import com.alibaba.cloud.commons.lang.StringUtils;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ruoyi.pojo.Hospital;
import com.ruoyi.pojo.Payment;
import com.ruoyi.service.HospitalService;
import com.ruoyi.service.PaymentService;
import com.ruoyi.until.R;
import com.ruoyi.vo.PageVo;
import io.jsonwebtoken.*;
import io.lettuce.core.RedisClient;
import org.aspectj.apache.bcel.classfile.Unknown;

import org.springframework.amqp.AmqpException;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cglib.core.Local;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.Lock;

/**
 * @author: liufei
 * @Desc:
 * @create: 2024-10-21 09:58
 **/
@RestController
@RequestMapping("/hospital")
public class HospitalController {

    @Autowired
    private HospitalService hospitalService;
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    PaymentService paymentService;

//    @Autowired
//    private RedissonClient redissonClient;





    @PostMapping("/list")
    public R list(@RequestBody PageVo pageVo,@RequestHeader String token){

        LambdaQueryWrapper<Hospital> wrapper = new LambdaQueryWrapper<>();

        wrapper.orderByAsc(Hospital::getDay);

        Page<Hospital> hospitalPage = new Page<>(pageVo.getPageNum(), pageVo .getPageSize());

        IPage<Hospital> hospitalIPage = hospitalService.page(hospitalPage,wrapper);

//        redisTemplate.opsForValue().set("hospitalList",hospitalIPage,30, TimeUnit.MINUTES);
        stringRedisTemplate.opsForValue().set("hospitalList", JSON.toJSONString(hospitalIPage));

        Claims claims = Jwts.parser().setSigningKey("bwie").parseClaimsJws(token).getBody();

        String role = claims.get("role", String.class);

        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("hospitalList",hospitalIPage);
        hashMap.put("roleData",role);

        return R.ok(hashMap);
    }

    @PostMapping("/paymentList")
    public R paymentList(){

        List<Payment> paymentList = paymentService.list();

        return R.ok(paymentList);
    }

    @PostMapping("/reser")
    @Transactional(rollbackFor = Exception.class)
    public R reser(@RequestBody Payment payment, @RequestHeader String token){

//        RLock lock = redissonClient.getLock("lock");
//
//        try {
//
//            lock.lock();
        Integer id = payment.getHospitalId();
        Payment payment1 = new Payment();
        payment1.setHospitalId(id);
        payment1.setMethod(payment.getMethod());
        if(StringUtils.isEmpty(payment.getMethod())){
            payment1.setPayStatus("未支付");
        }else{
            payment1.setPayStatus("已支付");
        }
        payment1.setCancelReason(payment.getCancelReason());
        paymentService.save(payment1);

        if(payment1.getPayStatus().equals("未支付")){
            return R.ok();
        }

        Hospital hospitalServiceById = hospitalService.getById(id);

            if(hospitalServiceById.getSurplusNumber()<=0){
                return R.error("预约失败，剩余数量不足");
            }

            UpdateWrapper<Hospital> wrapper = new UpdateWrapper<>();

            wrapper.eq("id",id).setSql("surplus_number=surplus_number-1");

            boolean update = hospitalService.update(wrapper);

            Claims claims = Jwts.parser().setSigningKey("bwie").parseClaimsJws(token).getBody();

            String username = claims.get("username", String.class);

        Hospital hospitalServiceById1 = hospitalService.getById(id);
//        stringRedisTemplate.opsForValue().set(hospitalServiceById1.getDay(),username);
        stringRedisTemplate.opsForZSet().add("hospital:"+hospitalServiceById1.getDay(), String.valueOf(hospitalServiceById1.getId()),1);

            redisTemplate.opsForValue().set("username:"+id,username,30, TimeUnit.MINUTES);

            if(update){
                rabbitTemplate.convertAndSend("hospitalExchange","",id);
            }

//            lock.unlock();
//
//        } catch (Exception e) {
//
//            throw new RuntimeException(e);
//        }



        return R.ok();
    }

    @PostMapping("/update")
    public R updateById(@RequestBody Hospital hospital){

        hospitalService.updateById(hospital);

        return R.ok();
    }

    /**
     * 每天0点更新剩余数量
     */
//    @Scheduled(cron = "0 0 0 * * ?")
    @Scheduled(cron = "0 0/1 * * * ?")
    public void updateSurplusNumber(){

        List<Hospital> hospitalList = hospitalService.list();


        System.out.println("-----------每日更新----------");
        System.out.println("-----------每日更新----------");
        System.out.println("-----------每日更新----------");
        System.out.println("冲突测试");
        System.out.println("冲突测试");
        System.out.println("冲突测试");
        System.out.println("冲突测试");

//        redisTemplate.opsForValue().set("hospitalList",hospitalList,30, TimeUnit.MINUTES);

        stringRedisTemplate.opsForValue().set("hospitalList", JSON.toJSONString(hospitalList));
    }

}
